package ;

import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import openfl.Assets;
import flash.display.Bitmap;
import flash.events.Event;
import flash.Lib;

/**
 * ...
 * @author test
 */
//--------- TODO don't make it inherit from Sprite, is an engine, the sprite should be somewhere deeper.
class Engine extends Sprite {
	private var inited:Bool = false;

	private var background:Bitmap;

	private var startTime:Int;

	private var player:Player;

	private var enemyPool:ObjectPool<Enemy>;

	//Constructor... nothing else to say here.
	public function new() {
		super();
		this.init();
		this.startGame();
	}

	//Getters and setters - BEGIN
	private function getInited():Bool {
		return this.inited;
	}

	private function setInited(inited:Bool):Void {
		this.inited = inited;
	}

	private function getBackground():Bitmap {
		return this.background;
	}

	private function setBackground(background:Bitmap):Void {
		this.background = background;
	}

	private function getStartTime():Int {
		return this.startTime;
	}

	private function setStartTime(startTime:Int):Void {
		this.startTime = startTime;
	}

	private function getPlayer():Player {
		return this.player;
	}

	private function setPlayer(player:Player):Void {
		this.player = player;
	}

	private function getEnemyPool():ObjectPool<Enemy> {
		return this.enemyPool;
	}

	private function setEnemyPool(enemyPool:ObjectPool<Enemy>):Void {
		this.enemyPool = enemyPool;
	}
	//Getters and setters - END

	//Method to init engine.
	private function init():Void {
		//TODO: It was taken from a tutorial, then some modifications where added. Review.
		if (!this.getInited()) {
			Lib.current.stage.align = flash.display.StageAlign.TOP_LEFT;
			Lib.current.stage.scaleMode = flash.display.StageScaleMode.NO_SCALE;

			//Added.
			this.setStartTime(0);
			this.setEnemyPool(new ObjectPool<Enemy>(5));

			this.setBackground(new Bitmap(Assets.getBitmapData("images/background.jpg")));
			this.addChild(this.getBackground());

			this.setPlayer(new Player());
			this.addChild(this.getPlayer());

			this.setInited(true);
		} else {
			return;
		}
	}

	//Method to start game.
	private function startGame():Void {
		this.setStartTime(Lib.getTimer());
		this.addEventListener(Event.ENTER_FRAME,onEnterFrame);
	}

	//Method bound to event ENTER_FRAME.
	private function onEnterFrame(event:Event):Void {
		var elapsedTime:Float = (Lib.getTimer() - this.getStartTime()) / 1000;

		var newEnemy:Enemy = null;

		if (elapsedTime >= 1) {
			newEnemy = this.getEnemyPool().getAvailableObject();
			if (newEnemy != null) {
				newEnemy.init();
				//TODO: See if "remove child" is needed when the enemy is killed
				this.addChild(newEnemy);
			}
			this.setStartTime(Lib.getTimer());
		}

		//Rudimentary collision processing
		for(i in 0...this.getEnemyPool().getObjects().length) {
			if (this.getEnemyPool().getObjects()[i].visible) {
				if (this.getEnemyPool().getObjects()[i].hitTestObject(this.getPlayer())) {
					this.getPlayer().stopDrag();
					this.getPlayer().x = this.getPlayer().x + 25;
				}
			}
		}
	}
}